package com.aididi.aspect;

import com.aididi.annotation.LogAnnotation;
import com.aididi.entity.SysLog;
import com.aididi.service.ISysLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

/**
 * @Auther: zx.xu
 * @Description:    aop切面处理日志
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    @Autowired
    private ISysLogService sysLogService;

    /**
     * 横切点
     * 表示匹配带有自定义注解的方法
     */
    @Pointcut("@annotation(com.aididi.annotation.LogAnnotation)")
    public void pointcut(){
    }

    /**
     * 横切面
     * 环绕通知，可以在目标方法执行前后执行一些操作，以及目标方法抛出异常时执行的操作。
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point){
        Object result =null;
        long beginTime = System.currentTimeMillis();

        try {
            log.info("我在目标方法之前执行！");
            result = point.proceed();
            long endTime = System.currentTimeMillis();
            insertLog(point,endTime-beginTime);
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }

    private void insertLog(ProceedingJoinPoint point,long time){
        MethodSignature signature = (MethodSignature)point.getSignature();
        Method method = signature.getMethod();
        SysLog sys_log = new SysLog();

        LogAnnotation userAction = method.getAnnotation(LogAnnotation.class);
        if (userAction != null) {
            // 注解上的描述
            sys_log.setUserAction(userAction.value());
        }

        // 请求的类名
        String className = point.getTarget().getClass().getName();
        // 请求的方法名
        String methodName = signature.getName();
        // 请求的方法参数值
        String args = Arrays.toString(point.getArgs());

        //应该从session中获取当前登录人的id，这里简单模拟下
        int userid = 2;
        sys_log.setUserId(userid);
        sys_log.setCreateTime(new java.sql.Timestamp(System.currentTimeMillis()));

        log.info("当前登陆人：{},类名:{},方法名:{},参数：{},执行时间：{}",userid, className, methodName, args, time);
        sysLogService.insertLog(sys_log);


    }

}
